﻿#include "AllData.h"
#include "SeatOccupy.h"
#include <fstream>
#include <sstream>
#include <iostream>
#include <string>
#include <vector>
#include <Constants.h>
#include "trains.h"

//关于用户的函数
int AllData::User_ReadFromFile(const char filename[]) {
    std::ifstream file(filename);
    if (!file.is_open()) {
        throw std::runtime_error("Failed to open file: " + std::string(filename));
    }

    int count = 0;
    std::string line;

    // 如果文件有标题行，可以取消注释以下行，这个代码相当于跳过第一行
    //std::getline(file, line);

    while (std::getline(file, line)) {
        // 移除行尾的\r（Windows换行符兼容）
        if (!line.empty() && line.back() == '\r') {
            line.pop_back();
        }

        // 跳过空行和注释行，感觉可用可不用
        if (line.empty() || line.find('#') == 0) continue;

        std::vector<std::string> fields;
        std::istringstream ss(line);
        std::string field;

        // 解析逗号分隔的字段
        while (std::getline(ss, field, ',')) {
            fields.push_back(field);
        }

        // 验证字段数量（应为7个），只要文件不出问题，用不到
        //if (fields.size() != 7) {
        //    std::cerr << "跳过无效记录（字段数量错误，应为7个，实际为"
        //        << fields.size() << "）: " << line << "\n";
        //    continue;
        //}

        try {
            // 创建用户对象并设置字段
            users user;
            user.setUserId(fields[0]);
            user.setUsername(fields[1]);
            user.setDisplayName(fields[2]);
            user.setPassword(fields[3]);  // 密码字段
            user.setPhone(fields[4]);     // 电话字段

            // 设置用户角色
            user.setRole(fields[5]);

            // 设置身份证号
            user.setIdCard(fields[6]);  // 新增身份证号字段

			user.setState(fields[7]);

            // 添加到用户集合
            usersQueue.push_back(user);
            count++;

        }
        catch (const std::exception& e) {
            std::cerr << "处理记录出错: " << line << "\n"
                << "原因: " << e.what() << "\n";
        }
    }
    file.close();
    return count;  // 返回成功读取的用户数量
}

int AllData::User_WriteToFile(const char filename[]) {
    std::ofstream file(filename);
    if (!file.is_open()) {
        throw std::runtime_error("无法打开文件: " + std::string(filename));
    }

    int count = 0;

    // 写入CSV表头,如果文件有标头
    /*file << "user_id,username,display_name,password,phone,role,id_card\n";*/

    // 遍历所有用户
    for (auto it = usersQueue.begin(); it != usersQueue.end(); ++it) {
        users user = *it;
        // 确保所有字段都有值
        //if (user.getUserId().empty() || user.getUsername().empty() ||
        //    user.getPassword().empty() || user.getPhone().empty() ||
        //    user.getIdCard().empty()) {
        //    std::cerr << "跳过不完整用户记录: ID=" << user.getUserId() << "\n";
        //    continue;
        //}

        // 写入逗号分隔的字段
        file << user.getUserId() << ","
            << user.getUsername() << ","
            << user.getDisplayName() << ","
            << user.getPassword() << ","
            << user.getPhone() << ","
            << user.getRole() << ","
            << user.getIdCard() << ","
            << user.getState() << "\n";
        count++;
    }

    file.close();

    if (file.fail()) {
        throw std::runtime_error("写入文件时出错: " + std::string(filename));
    }

    return count;  // 返回成功写入的用户数量
}


//关于列车计划的函数
int AllData::Train_Schedeles_ReadFromFile(const char filename[])
{
    std::ifstream file(filename);
    if (!file.is_open()) {
        throw std::runtime_error("Failed to open file: " + std::string(filename));
    }
    int count = 0;
    std::string line;

    while (std::getline(file, line)) {
        // 移除行尾的\r（Windows换行符兼容）
        if (!line.empty() && line.back() == '\r') {
            line.pop_back();
        }

        // 跳过空行和注释行
        if (line.empty() || line.find('#') == 0) continue;

        std::vector<std::string> fields;
        std::istringstream ss(line);
        std::string field;

        // 解析逗号分隔的字段
        while (std::getline(ss, field, ',')) {
            fields.push_back(field);
        }

        try {
            // ==== 关键修复：处理缺失的出发时间 ====
            if (fields.size() == 5) {
                // 添加一个空字符串作为缺失的depart_time
                fields.push_back("");
            }

            // 检查字段数量
            if (fields.size() != 6) {
                throw std::runtime_error("Invalid field count. Expected 6, got " + std::to_string(fields.size()));
            }

            // 创建火车对象并设置字段
            train_schedule train_s;
            int s_id = std::stoi(fields[0]);
            int train_id = std::stoi(fields[1]);
            int station_id = std::stoi(fields[2]);
            int stop_order = std::stoi(fields[3]);

            // 处理时间字段：允许空字符串
            std::string arrival_time = fields[4];
            std::string depart_time = fields[5];

            train_s.setScheduleId(s_id);
            train_s.setTrainId(train_id);
            train_s.setStationId(station_id);
            train_s.setStopOrder(stop_order);

            // 设置时间（允许空值）
            train_s.setArrivalTime(arrival_time);
            train_s.setDepartTime(depart_time);

            // 添加到火车计划集合
            trainSchedules.push_back(train_s);
            count++;
        }
        catch (const std::exception& e) {
            std::cerr << "处理记录出错: " << line << "\n"
                << "原因: " << e.what() << "\n";
        }
    }
    return count;
}
int AllData::Train_Schedeles_WriteToFile(const char filename[])
{
    std::ofstream file(filename);
    if (!file.is_open()) {
        throw std::runtime_error("无法打开文件: " + std::string(filename));
    }
    int count = 0;
    for (auto it = trainSchedules.begin(); it != trainSchedules.end(); ++it) {
        train_schedule sch = *it;
        file << sch.getScheduleId() << ","
            << sch.getTrainId() << ","
            << sch.getStationId() << ","
            << sch.getStopOrder() << ","
            << (sch.getArrivalTime().empty() ? "" : sch.getArrivalTime()) << ","
            << (sch.getDepartTime().empty() ? "" : sch.getDepartTime()) << "\n";
        count++;
    }
    file.close();
    if (file.fail()) {
        throw std::runtime_error("写入文件时出错: " + std::string(filename));
    }
    return count;  // 返回成功写入的时刻表数量
}

//关于站点的函数
int AllData::Station_ReadFromFile(const char filename[])
{
	std::ifstream file(filename);
    if (!file.is_open()) {
        throw std::runtime_error("Failed to open file: " + std::string(filename));
    }
    int count = 0;
    std::string line;
    while (std::getline(file, line)) {
        // 移除行尾的\r（Windows换行符兼容）
        if (!line.empty() && line.back() == '\r') {
            line.pop_back();
        }
        // 跳过空行和注释行，感觉可用可不用
        if (line.empty() || line.find('#') == 0) continue;
        std::vector<std::string> fields;
        std::istringstream ss(line);
        std::string field;
        // 解析逗号分隔的字段
        while (std::getline(ss, field, ',')) {
            fields.push_back(field);
        }
        try {
            // 创建车站对象并设置字段
            stations station;
            int station_id = std::stoi(fields[0]);
            std::string station_name = fields[1];
            double distance = 0.0;
            if (fields.size() > 2) {
                distance = std::stod(fields[2]);
            }
            station.setStationId(station_id);
            station.setName(station_name);
            station.setDistance(distance);
            // 添加到车站集合
            stationsQueue.push_back(station);
            count++;
        }
        catch (const std::exception& e) {
            std::cerr << "处理记录出错: " << line << "\n"
                << "原因: " << e.what() << "\n";
        }
	}
	return count;  // 返回成功读取的车站数量
}

int AllData::Station_WriteToFile(const char filename[])
{
	std::ofstream file(filename);
    if (!file.is_open()) {
        throw std::runtime_error("无法打开文件: " + std::string(filename));
    }
    int count = 0;
    for (auto it = stationsQueue.begin(); it != stationsQueue.end(); ++it) {
        stations station = *it;
        file << station.getStationId() << ","
            << station.getName() << ","
            << station.getDistance() << "\n";
        count++;
    }
    file.close();
    if (file.fail()) {
        throw std::runtime_error("写入文件时出错: " + std::string(filename));
	}
	return count;  // 返回成功写入的车站数量
}


//关于座位的函数
int AllData::Seat_ReadFromFile(const char filename[])
{
	std::ifstream file(filename);
    if (!file.is_open()) {
        throw std::runtime_error("Failed to open file: " + std::string(filename));
    }
    //int seat_id;
    //int train_id;
    //std::string seat_no;
    //std::string seat_type;
    int count = 0;
    std::string line;
    while (std::getline(file, line)) {
        // 移除行尾的\r（Windows换行符兼容）
        if (!line.empty() && line.back() == '\r') {
            line.pop_back();
        }
		// 跳过空行和注释行，感觉可用可不用
        if (line.empty() || line.find('#') == 0) continue;
        std::vector<std::string> fields;
        std::istringstream ss(line);
        std::string field;
        // 解析逗号分隔的字段
        while (std::getline(ss, field, ',')) {
            fields.push_back(field);
        }
        try {
            // 创建座位对象并设置字段
            seats seat;
            int seat_id = std::stoi(fields[0]);
            int train_id = std::stoi(fields[1]);
            std::string seat_no = fields[2];
            std::string seat_type = fields[3];
            seat.setSeatId(seat_id);
            seat.setTrainId(train_id);
            seat.setSeatNo(seat_no);
            seat.setSeatType(seat_type);
            // 添加到座位集合
            seatsQueue.push_back(seat);
            count++;
        }
        catch (const std::exception& e) {
            std::cerr << "处理记录出错: " << line << "\n"
                << "原因: " << e.what() << "\n";
		}
	}
	return count;  // 返回成功读取的座位数量
}

int AllData::Seat_WriteToFile(const char filename[])
{
    std::ofstream file(filename);
    if (!file.is_open()) {
        throw std::runtime_error("无法打开文件: " + std::string(filename));
    }
    int count = 0;
    for (auto it = seatsQueue.begin(); it != seatsQueue.end(); ++it) {
        seats seat = *it;
        file << seat.getSeatId() << ","
            << seat.getTrainId() << ","
            << seat.getSeatNo() << ","
            << seat.getSeatType() << "\n";
            count++;
    }
    file.close();
    if (file.fail()) {
        throw std::runtime_error("写入文件时出错: " + std::string(filename));
	}
	return count;  // 返回成功写入的座位数量
}

//关于订单的函数
int AllData::Order_ReadFromFile(const char filename[])
{
    ordersQueue.clear();
    std::ifstream file(filename);
    if (!file.is_open()) {
        throw std::runtime_error("Failed to open file: " + std::string(filename));
    }
    int count = 0;
    std::string line;
    while (std::getline(file, line)) {
        if (!line.empty() && line.back() == '\r') {
            line.pop_back();
        }
        // 跳过空行和注释行，感觉可用可不用
        if (line.empty() || line.find('#') == 0) continue;
        std::vector<std::string> fields;
        std::istringstream ss(line);
        std::string field;
        // 解析逗号分隔的字段
        while (std::getline(ss, field, ',')) {
            fields.push_back(field);
        }
        try {
            // 创建订单对象并设置字段
            orders order;
            int order_id = std::stoi(fields[0]);
            int user_id = std::stoi(fields[1]);
            int train_id = std::stoi(fields[2]);
            int seat_id = std::stoi(fields[3]);
            int start_station_id = std::stoi(fields[4]);
            int end_station_id = std::stoi(fields[5]);
            std::string travel_date = fields[6];
            std::string order_time = fields[7];
            std::string status = fields[8];
            double price = fields.size() > 9 ? std::stod(fields[9]) : 0.0;
            order.setOrderId(order_id);
            order.setUserId(user_id);
            order.setTrainId(train_id);
            order.setSeatId(seat_id);
            order.setStartStationId(start_station_id);
            order.setEndStationId(end_station_id);
            order.setTravelDate(travel_date);
            order.setOrderTime(order_time);
            order.setPrice(price);
            orders::OrderStatus statusEnum;
            if (status == "booked") statusEnum = orders::booked;
            else if (status == "canceled") statusEnum = orders::canceled;
            else if (status == "changed") statusEnum = orders::changed;
            else statusEnum = orders::booked;
            order.setStatus(statusEnum);
            ordersQueue.push_back(order);
            count++;
        }
        catch (const std::exception& e) {
            std::cerr << "处理记录出错: " << line << "\n"
                << "原因: " << e.what() << "\n";
        }
    }
    return count;
}

int AllData::Order_WriteToFile(const char filename[])
{
    std::ofstream file(filename);
    if (!file.is_open()) {
        throw std::runtime_error("无法打开文件: " + std::string(filename));
    }
    int count = 0;
    for (auto it = ordersQueue.begin(); it != ordersQueue.end(); ++it) {
        orders order = *it;
        std::string statusStr;
        switch (order.getStatus()) {
            case orders::booked: statusStr = "booked"; break;
            case orders::canceled: statusStr = "canceled"; break;
            case orders::changed: statusStr = "changed"; break;
            default: statusStr = "booked"; break;
        }
        file << order.getOrderId() << ","
            << order.getUserId() << ","
            << order.getTrainId() << ","
            << order.getSeatId() << ","
            << order.getStartStationId() << ","
            << order.getEndStationId() << ","
            << order.getTravelDate() << ","
            << order.getOrderTime() << ","
            << statusStr << ","
            << order.getPrice() << "\n";
        count++;
    }
    file.close();
    if (file.fail()) {
        throw std::runtime_error("写入文件时出错: " + std::string(filename));
    }
    return count;  // 返回成功写入的订单数量
}

//关于列车的函数
int AllData::Train_ReadFromFile(const char filename[])
{
    std::ifstream file(filename);
    if (!file.is_open()) {
        throw std::runtime_error("Failed to open file: " + std::string(filename));
    }
    int count = 0;
    std::string line;
    // 如果文件有标题行，可以取消注释以下行，这个代码相当于跳过第一行
    //std::getline(file, line);


    //int train_id; // 火车ID
    //std::string train_code; // 火车编号
    //char type; // 火车类型
    //int start_station_id; // 起始站ID	
    //int end_station_id; // 终点站ID

    while (std::getline(file, line)) {
        // 移除行尾的\r（Windows换行符兼容）
        if (!line.empty() && line.back() == '\r') {
            line.pop_back();
        }
        // 跳过空行和注释行，感觉可用可不用
        if (line.empty() || line.find('#') == 0) continue;
        std::vector<std::string> fields;
        std::istringstream ss(line);
        std::string field;
        // 解析逗号分隔的字段
        while (std::getline(ss, field, ',')) {
            fields.push_back(field);
        }
        try {
            // 创建火车对象并设置字段
            trains train;
            int train_id = std::stoi(fields[0]);
            std::string train_code = fields[1];
            char type = fields[2][0]; // 假设type是单个字符
            int start_station_id = std::stoi(fields[3]);
            int end_station_id = std::stoi(fields[4]);
            train.setTrainId(train_id);
            train.setTrainCode(train_code);
            train.setType(type);
            train.setStartStationId(start_station_id);
            train.setEndStationId(end_station_id);
            // 添加到火车集合
            trainQueue.push_back(train);
            count++;
        }
        catch (const std::exception& e) {
            std::cerr << "处理记录出错: " << line << "\n"
                << "原因: " << e.what() << "\n";
        }
    }
	return count;  // 返回成功读取的火车数量
}

int AllData::Train_WriteToFile(const char filename[])
{
    std::ofstream file(filename);
    if (!file.is_open()) {
        throw std::runtime_error("无法打开文件: " + std::string(filename));
    }

    int count = 0;

    for (auto it = trainQueue.begin(); it != trainQueue.end(); ++it) {
        trains train = *it;
        file << train.getTrainId()<<","
            << train.getTrainCode() << ","
            << train.getType() << ","
            << train.getStartStationId() << ","
            << train.getEndStationId() << ","
            << "\n";

        count++;
    }

    file.close();

    if (file.fail()) {
        throw std::runtime_error("写入文件时出错: " + std::string(filename));
    }

    return count;  // 返回成功写入的用户数量

}
// 票价计算：seatType为"商务座"/"一等座"/"二等座"
double AllData::CalculateTicketPrice(int startStationId, int endStationId, const std::string& seatType, const std::deque<stations>& stationsQueue) {
    double startDist = -1, endDist = -1;
    for (const auto& st : stationsQueue) {
        if (st.getStationId() == startStationId) startDist = st.getDistance();
        if (st.getStationId() == endStationId) endDist = st.getDistance();
    }
    if (startDist < 0 || endDist < 0) return -1; // 异常：缺少距离
    double rate = 0.0;
    if (seatType == "商务座") rate = 0.8;
    else if (seatType == "一等座") rate = 0.5;
    else if (seatType == "二等座") rate = 0.3;
    else return -1; // 异常：未知座位类型
    return std::abs(endDist - startDist) * rate;
}

int AllData::SeatOccupy_ReadFromFile(const char filename[])
{
    seatOccupyQueue.clear();
    std::ifstream file(filename);
    if (!file.is_open()) {
        return 0; // 文件不存在时视为无占用
    }
    int count = 0;
    std::string line;
    while (std::getline(file, line)) {
        if (!line.empty() && line.back() == '\r') line.pop_back();
        if (line.empty() || line.find('#') == 0) continue;
        std::vector<std::string> fields;
        std::istringstream ss(line);
        std::string field;
        while (std::getline(ss, field, ',')) fields.push_back(field);
        if (fields.size() < 7) continue;
        SeatOccupy so;
        so.setDate(fields[0]);
        so.setTrainId(std::stoi(fields[1]));
        so.setSeatId(std::stoi(fields[2]));
        so.setSeatNo(fields[3]);
        so.setStartStationId(std::stoi(fields[4]));
        so.setEndStationId(std::stoi(fields[5]));
        so.setOrderId(std::stoi(fields[6]));
        seatOccupyQueue.push_back(so);
        count++;
    }
    return count;
}

int AllData::SeatOccupy_WriteToFile(const char filename[])
{
    std::ofstream file(filename);
    if (!file.is_open()) {
        throw std::runtime_error("无法打开文件: " + std::string(filename));
    }
    int count = 0;
    // 写入表头，便于人工检查
    // file << "IF U CAN READ THIS, PROVING IT WORKS\n";
    for (const auto& so : seatOccupyQueue) {
        // 保证每个字段都写入，seat_no为空时写EMPTY
        file << (so.getDate().empty() ? "EMPTY" : so.getDate()) << ","
            << so.getTrainId() << ","
            << so.getSeatId() << ","
            << (so.getSeatNo().empty() ? "EMPTY" : so.getSeatNo()) << ","
            << so.getStartStationId() << ","
            << so.getEndStationId() << ","
            << so.getOrderId() << "\n";
        count++;
    }
    file.close();
    if (file.fail()) {
        throw std::runtime_error("写入文件时出错: " + std::string(filename));
    }
    return count;
}

bool AllData::IsSeatAvailable(const std::string& date, int train_id, int seat_id, int start_station_id, int end_station_id) {
    for (const auto& so : seatOccupyQueue) {
        if (so.getDate() == date && so.getTrainId() == train_id && so.getSeatId() == seat_id) {
            // 区间重叠判断
            if (!(end_station_id <= so.getStartStationId() || so.getEndStationId() <= start_station_id)) {
                return false;
            }
        }
    }
    return true;
}
